package nameless.aistudy.domain.service.statistics.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import nameless.aistudy.domain.model.statistics.Statistics;
import nameless.aistudy.domain.model.statistics.StatisticsRepo;
import nameless.aistudy.domain.service.statistics.StatisticsService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;

@Service
public class StatisticsServiceImpl extends ServiceImpl<StatisticsRepo, Statistics> implements StatisticsService {

    /**
     * 获取用户的统计数据
     *
     * @param userId 用户ID
     * @param typeId 类型ID
     * @param date   日期
     * @return 统计数据对象，如果不存在则返回 null
     */
    @Override
    public Statistics getUserStatistics(int userId, long typeId, LocalDate date) {
        LambdaQueryWrapper<Statistics> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Statistics::getUserId, userId)
                .eq(Statistics::getTypeId, typeId)
                .eq(Statistics::getDate, date)
                .eq(Statistics::getIsDeleted, false);

        return getOne(queryWrapper);
    }

    /**
     * 添加或更新用户的统计数据
     * 如果当天的统计数据已存在，则更新；如果不存在，则新增。
     *
     * @param userId 用户ID
     * @param typeId 类型ID
     * @param date   日期
     * @param amount 要增加的金额
     * @return 操作是否成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class) // 保证事务的原子性
    public boolean addUserStatistics(int userId, long typeId, LocalDate date, BigDecimal amount) {
        // 1. 首先尝试获取当天的统计数据
        Statistics statistics = getUserStatistics(userId, typeId, date);

        if (statistics != null) {
            // 2. 如果数据存在，则进行更新
            // 更新 daily 和 overall 字段
            statistics.setDaily(statistics.getDaily().add(amount));
            statistics.setOverall(statistics.getOverall().add(amount));

            // 使用 updateById 方法更新数据库
            return updateById(statistics);
        } else {
            // 3. 如果数据不存在，则创建一个新的统计记录
            LambdaQueryWrapper<Statistics> historyQueryWrapper = new LambdaQueryWrapper<>();
            historyQueryWrapper.eq(Statistics::getUserId, userId)
                    .eq(Statistics::getTypeId, typeId)
                    .lt(Statistics::getDate, date)
                    .orderByDesc(Statistics::getDate) // 按日期降序排序，确保第一条是最近的
                    .last("LIMIT 1"); // 只取一条

            Statistics latestHistoryRecord = getOne(historyQueryWrapper);

            // 3.2 计算新的 overall 值
            BigDecimal overallAmount;
            if (latestHistoryRecord != null) {
                overallAmount = latestHistoryRecord.getOverall().add(amount);
            } else {
                overallAmount = amount;
            }

            statistics = new Statistics();
            statistics.setUserId(userId);
            statistics.setTypeId(typeId);
            statistics.setDate(date);
            statistics.setDaily(amount);
            statistics.setOverall(overallAmount);

            // 使用 save 方法插入新数据到数据库
            return save(statistics);
        }
    }

    @Override
    public boolean setUserStatistics(int userId, long typeId, LocalDate date, BigDecimal dailyAmount, BigDecimal overallAmount) {
        Statistics statistics = new Statistics();
        statistics.setUserId(userId);
        statistics.setTypeId(typeId);
        statistics.setDate(date);
        statistics.setDaily(dailyAmount);
        statistics.setOverall(overallAmount);

        return saveOrUpdate(statistics);
    }
}
